<?php
/**
 * A static toolkit to get and create rail_object objects.
 *
 **
 * PHP versions 5
 * See http://www.open-rail.org for more informations.
 *
 **
 * Copyright (C)
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of ERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software
 * Fundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
 *
 **
 * @author Bastian Schröder <bastian@open-rail.org>
 * @version 2009-05-14
 * @package rail
 */
class rail_factory {
	
	
	/**
	 * Create a new rail_object. By default the type of the created rail_object will be RAIL_OBJECT, but it's possible
	 * to set the type to a user defined or an other rail core object class.
	 *
	 * @param rail_connector $pRailConnector
	 * @param rail_object $pEnvironment
	 * @param string $pName OBJ_NAME (optional)
	 * @param string $pRailType (optional)
	 * @return rail_object
	 */	
	public static function create_object ( $pRailConnector, $pEnvironment, $pName = 'untitled', $pRailType = RAIL_OBJECT ) {
		// call create methode on pRailType class if class exists
		if( class_exists( strtolower( $pRailType ) ) ){
			$object = call_user_func( array( strtolower( $pRailType ), 'create' ), $pRailConnector, $pEnvironment, $pName );
		}
		// create new rail_object and set type to unsupportet string pRailType
		else{
			$object = rail_object::create( $pRailConnector, $pEnvironment, $pName = 'untitled' );
			$pRailConnector->send_request( "UPDATE " . $pRailConnector->mysql_table_prefix . "objects SET `type`='" . strtoupper( $pRailType ) . "' WHERE `id`='" . $object->get_id() . "'" );
		}
		
		// return new object
		return $object;
	}

	/**
	 * Get object from RAIL. Requires a valid rail_id or a valid rail_path. If a PHP class file exist with rail_object
	 * Objects type return this class. Otherwise return a rail_object.
	 *
	 * @exception rail_exception
	 * @param rail_connector $pRailConnector
	 * @param mixed $pObject a rail_id or a rail_path.
	 * @return mixed
	 */
	public static function get_object ( $pRailConnector, $pObject ) {
		// locate objects rail_id if pObject is a rail_path
		if( !is_numeric($pObject) ){
			$path = trim( $pObject );
			
			// remove last slash, if exist
			if( substr( $path, - 1 ) == '/' )
				$path = substr( $path, 0, strlen($path) - 1 );
				
			// explode path to array and remove first array object (root path)
			$path = explode( '/', $path );
			unset( $path[0] );
			
			// return rail_root if path is a valid path to rail_root
			if( count($path) == 0 )
				return $pRailConnector->get_root();
				
			// set environment to rail_root id
			$environment = $pRailConnector->get_root()->get_id();
			
			// for each path do
			foreach( $path as $tracker ){
				$name = substr($tracker, 0, strrpos( $tracker, '[' )?strrpos( $tracker, '[' ):strlen($tracker) );
				
				// search for name in environments inventory
				$data = $pRailConnector->send_request(
					"SELECT " . $pRailConnector->mysql_table_prefix . "objects.id
					 FROM " . $pRailConnector->mysql_table_prefix . "objects," . $pRailConnector->mysql_table_prefix . "objects_attributes
					 WHERE " . $pRailConnector->mysql_table_prefix . "objects.id = " . $pRailConnector->mysql_table_prefix . "objects_attributes.object AND " . $pRailConnector->mysql_table_prefix . "objects.environment ='$environment' AND " . $pRailConnector->mysql_table_prefix . "objects_attributes.`attribute` = 'OBJ_NAME' AND " . $pRailConnector->mysql_table_prefix . "objects_attributes.`value` = '" . urldecode( $name ) . "' ORDER BY `id`"
				);
				
				// store all founded objects as id in an array
				$possible_objects = array();
				while( ($data_row = $data->fetch_assoc()) )
					$possible_objects[] = $data_row['id'];
					
				// throw an exception if name not found in environments inventory
				if( count($possible_objects) <= 0 )
					throw new rail_exception( null, 'Object dosn\'t exist!' );
					
				// get next environment
				$environment = $possible_objects[ (strrpos( $tracker, '[' ) ? substr( $tracker, strrpos( $tracker, '[' ) + 1, strlen( $tracker ) - strrpos( $tracker, '[' ) - 2 ) - 1 : 0) ];
			}
			
			// last founded environment is the requested object id
			$pObject = $environment;
		}

		// try to finger out the type for the RAIL object.
		$data = $pRailConnector->send_request( "SELECT `type` FROM " . $pRailConnector->mysql_table_prefix . "objects WHERE `id`='$pObject' LIMIT 1" )->fetch_assoc();
		
		// throw an exception, if the requested rail_object object dosn't exist.
		if( count( $data ) <= 0 )
			throw new rail_exception( null, 'Object dosn\'t exist!' );
			
		// return rail_object
		$class = class_exists( strtolower( $data[ 'type' ] ) ) ? strtolower( $data[ 'type' ] ) : 'rail_object';
		return new $class( $pRailConnector, $pObject );
	}


	/**
	 * Return rail_object if object exist otherwise return false.
	 *
	 * @param rail_connector $pRailConnector
	 * @param mixed $pObject a rail_id or a rail_path.
	 * @return mixed
	 */
	public static function is_object ( $pRailConnector, $pObject ) {
		try{
			return rail_factory::get_object( $pRailConnector, $pObject );
		}
		catch( rail_exception $e ){
			return false;
		}
	}


	/**
	 * *alpha*
	 * Search for objects by attributes or types. Return array of rail_objects.
	 *
	 * @param rail_connector $pRailConnector
	 * @param array $pMatchAttributes (not supported yet)
	 * @param string $pRailTypes (op tional)
	 * @return array
	 */
	/*public static function search ( $pRailConnector, $pMatchAttributes, $pRailTypes = 'ALL' ) {
		// build SQL WHERE
		$sql_where_types = '';
		if( strlen($pRailTypes) > 0 && $pRailTypes != 'ALL' ){
			foreach( explode('|', $pRailTypes) as $type )
				$sql_where_types .= " OR `type`='$type'";

			$sql_where_types = ' AND(' . substr($sql_where_types, 4) . ')';
		}

		// search for objects
		$data = $pRailConnector->send_request("
			SELECT DISTINCT " . $pRailConnector->mysql_table_prefix . "objects.id
			FROM " . $pRailConnector->mysql_table_prefix . "objects," . $pRailConnector->mysql_table_prefix . "objects_attributes
			WHERE " . $pRailConnector->mysql_table_prefix . "objects.id = " . $pRailConnector->mysql_table_prefix . "objects_attributes.object
			$sql_where_types
		");

		// store all objects from search result into return array
		$objects = array();
		while( ($data_row = $data->fetch_assoc()) )
			$objects[] = rail_factory::get_object( $pRailConnector, $data_row['id'] );

		return $objects;
	}*/

} // End of rail_factory
?>